extends PropertyComponent


class_name RangeComponent
"""
带范围限制的数据组件(如:HP,MP)
"""


const key_value: String = "value"
const key_min_value: String = "min_value"
const key_max_value: String = "max_value"


## RangeComponent中的可调用接口
enum RangeMethod {
    None,     ## 不执行任何操作
    Increase, ## 增加值
    Decrease, ## 减少值
    Done,     ## 消耗所有值
    Full,     ## 充满所有值
    Set,      ## 设置值
    SetMin,   ## 设置最小值
    SetMax,   ## 设置最大值
}

## 当前值
@export var value: int = 100:
    set(v):
        if is_node_ready() and v != value:
            value = __set_value(key_value, value, v)
            __update_progress()
        else:
            value = v
## 最小值
@export var min_value: int = 0:
    set(v):
        min_value = __set_value(key_min_value, min_value, v)
## 最大值
@export var max_value: int = 100:
    set(v):
        if __check_value(key_max_value, v):
            if value > v:
                value = __set_value(key_value, value, v, true)
            max_value = __set_value(key_max_value, max_value, v, true)

## 用于UI显示的组件
@export var progress_bar: Range = null


func __check_exports() -> Dictionary:
    return IComponent.merge({
        "max_value": func(): return max_value > min_value,
        "min_value": func(): return min_value < max_value,
        "value": func(): return (value >= min_value and value <= max_value),
        "progress_bar": [IComponent.find_down.bind(self, func(x): return x is Range, progress_bar)],
    }, super.__check_exports())

# 设置前校验数据
func __check_value(property: StringName, v: Variant) -> Variant:
    match property:
        "value": return clampi(v, min_value, max_value)
        "max_value": return v if v > min_value else null
        "min_value": return v if v < max_value else null
    return super.__check_value(property, v)

func __prepare() -> void:
    super.__prepare()
    value = __check_value(key_value, value)
    __update_progress()

func __update_progress() -> void:
    if progress_bar:
        progress_bar.value = progress_bar.max_value * value / max_value

# 是否已经消耗完
func is_done() -> bool:
    return value <= min_value

# 是否为满容状态
func is_full() -> bool:
    return value >= max_value

# 返回当前剩余容量
func capacity() -> int:
    return value - min_value

# 返回当前的空余量
func space() -> int:
    return max_value - value

# 受伤
func decrease(decrement: int) -> void:
    value = value - decrement

# 回复
func increase(increment: int) -> void:
    value = value + increment

# 增加值,多余的数据自动溢出,返回溢出次数
func increase_level(increment: int, upgrade_value: int = 0) -> int:
    var increment_value: int = increment
    var total: int = 0
    var level: int = 0
    while increment_value > 0:
        var space_value: int = space()
        # 还有容量
        if space_value > increment_value:
            value += increment_value
            total += increment_value
            break
        # 没有容量,升一级
        value = 0
        if upgrade_value > 0:
            max_value += upgrade_value
        level += 1
        increment_value -= space_value
        total += space_value
    return level

# 清空值,返回扣除的值
func done() -> void:
    value = min_value

# 充满值,返回恢复的值
func full() -> void:
    value = max_value

# 执行指定的动作
func execute(method: RangeMethod, value: int) -> void:
    match method:
        RangeMethod.None: pass
        RangeMethod.Increase: increase(value)
        RangeMethod.Decrease: decrease(value)
        RangeMethod.Done: done()
        RangeMethod.Full: full()
        RangeMethod.Set: self.value = value
        RangeMethod.SetMin: min_value = value
        RangeMethod.SetMax: max_value = value
